package com.central.apps.service.impl;

import com.central.app.service.HandlerService;
import com.central.apps.entity.CostAttribute;
import com.central.apps.entity.CostDetailAttribute;
import com.central.apps.service.BudgetService;
import com.central.apps.service.CostAccumulationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 成本归集接口实现类
 *
 * @author 李大超
 * @date 2023/1/10
 */
@Slf4j
@Service
public class CostAccumulationServiceImpl implements CostAccumulationService {

    @Autowired
    private HandlerService handlerService;
    @Autowired
    private BudgetService budgetService;

    /**
     * 成本归集
     *
     * @param costAttribute
     */
    @Override
    public void costAccumulation(CostAttribute costAttribute) throws Exception {
        // 组织成本单主数据
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("cfdesc", costAttribute.getName());// 成本单描述
        map.put("proid", costAttribute.getProId());// 项目id
        map.put("subjectno", costAttribute.getSubjectNo());// 课题号
        map.put("taskid", costAttribute.getTaskid());// 任务id
        map.put("totalcost", costAttribute.getTotalCost());// 总计金额
        map.put("orderid", costAttribute.getOrderId());// 关联合同/出入库等单据id
        map.put("orderno", costAttribute.getOrderNo());// 关联合同/出入库等单据编号
        map.put("type", costAttribute.getType() == null ? "支出" : costAttribute.getType());// 所属类型
        map.put("costsource", costAttribute.getCostSource());// 成本来源

        Integer costItemId = costAttribute.getCostItemId();

        if (costItemId != null) {
            // 查询年度预算信息
            Map<String, Object> pbMap = handlerService.findOneBySql("select * from gq_probudget where id = " + costItemId);

            if (pbMap.isEmpty()) {
                map.put("status", "未分配");
            } else {
                map.put("pbid", MapUtils.getInteger(pbMap,"id"));
                map.put("budgetitem", MapUtils.getString(pbMap,"budgetitem"));
                map.put("subjectnum", MapUtils.getInteger(pbMap,"subjectnum"));
                map.put("subjectdesc", MapUtils.getInteger(pbMap,"subjectdesc"));
                map.put("crdr", MapUtils.getInteger(pbMap,"crdr"));
                map.put("status", "已生成");
            }
        } else {
            map.put("status", "未分配");
        }

        // 生成项目成本单编码
        Map<String, Object> numMap = new HashMap<>();
        handlerService.addBizNum("procostfillApp", "gq_procostfill", numMap);
        String cfNum = MapUtils.getString(numMap, "cfnum");
        map.put("cfnum", cfNum);

        // 插入成本单主数据
        handlerService.insert("gq_procostfill", map);

        // 更新年度预算实际使用金额
        budgetService.updateBudgetInfo(costAttribute.getProId(), costItemId, costAttribute.getTotalCost());
    }

    /**
     * 物料成本归集
     *
     * @param costAttribute
     */
    @Override
    public void itemCostAccumulation(CostAttribute costAttribute) throws Exception {
        // 组织成本单主数据
        Map<String, Object> map = new HashMap<String, Object>();
        Integer proId = costAttribute.getProId();
        map.put("cfdesc", costAttribute.getName());// 成本单描述
        map.put("proid", proId);// 项目id
        map.put("subjectno", costAttribute.getSubjectNo());// 课题号
        map.put("taskid", costAttribute.getTaskid());// 任务id
        map.put("totalcost", costAttribute.getTotalCost());// 总计金额
        map.put("orderid", costAttribute.getOrderId());// 关联合同/出入库等单据id
        map.put("orderno", costAttribute.getOrderNo());// 关联合同/出入库等单据编号
        map.put("type", costAttribute.getType() == null ? "支出" : costAttribute.getType());// 所属类型
        map.put("costsource", costAttribute.getCostSource());// 成本来源

        Integer costItemId = costAttribute.getCostItemId();

        if (costItemId != null && costItemId > 0) {
            // 查询年度预算信息
            Map<String, Object> pbMap = handlerService.findOneBySql("select * from gq_probudget where id = " + costItemId);

            if (pbMap == null && pbMap.isEmpty()) {
                map.put("status", "未分配");
            } else {
                map.put("pbid", MapUtils.getInteger(pbMap,"id"));
                map.put("budgetitem", MapUtils.getInteger(pbMap,"budgetitem"));
                map.put("subjectnum", MapUtils.getInteger(pbMap,"subjectnum"));
                map.put("subjectdesc", MapUtils.getInteger(pbMap,"subjectdesc"));
                map.put("crdr", MapUtils.getInteger(pbMap,"crdr"));
                map.put("status", "已生成");
            }
        } else {
            map.put("status", "未分配");
        }

        // 生成项目成本单编码
        Map<String, Object> numMap = new HashMap<>();
        handlerService.addBizNum("procostfillApp", "gq_procostfill", numMap);
        String cfNum = MapUtils.getString(numMap, "cfnum");
        map.put("cfnum", cfNum);

        // 插入成本单主数据
        BigInteger pcfid = (BigInteger) handlerService.insert("gq_procostfill", map);

        // 更新年度预算实际使用金额
        budgetService.updateBudgetInfo(costAttribute.getProId(), costItemId, costAttribute.getTotalCost());

        List<CostDetailAttribute> costDetailAttributes = costAttribute.getCostDetailAttributes();

        if (CollectionUtils.isNotEmpty(costDetailAttributes)) {
            List<Map<String, Object>> costDetails = new ArrayList<>();
            for (CostDetailAttribute costDetailAttr : costDetailAttributes) {
                Map<String, Object> costDetailMap = new HashMap<>();
                costDetailMap.put("name", costDetailAttr.getName());
                costDetailMap.put("unitprice", costDetailAttr.getUnitPrice());
                costDetailMap.put("quantity", costDetailAttr.getQuantity());
                costDetailMap.put("totalprice", costDetailAttr.getTotalprice());
                costDetailMap.put("pcfid", pcfid);

                costDetails.add(costDetailMap);
            }

            if (CollectionUtils.isNotEmpty(costDetails)) {
                handlerService.batchInsert("procostfillApp", "gq_procostfillline", costDetails);
            }
        }
    }
}
